home *** CD-ROM | disk | FTP | other *** search
- /*
- * FednetCmp - Fednet file compression/decompression
- * Main application skeleton
- * Copyright (C) 2001 Chris Bazley
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public Licence as published by
- * the Free Software Foundation; either version 2 of the Licence, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public Licence for more details.
- *
- * You should have received a copy of the GNU General Public Licence
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- /* ANSI library files */
- #include <stdlib.h>
- #include <string.h>
- #ifdef DEBUG
- #include <stdio.h>
- #endif
- #include <stdbool.h>
- #include <signal.h>
- #include <ctype.h>
-
- /* RISC OS library files */
- #include "kernel.h"
- #include "toolbox.h"
- #include "event.h"
- #include "flex.h"
- #include "wimp.h"
- #include "wimplib.h"
-
- /* My library files */
- #include "err.h"
- #include "msgtrans.h"
- #include "hourglass.h"
- #include "FedCompMT.h"
- #include "Macros.h"
- #include "Loader.h"
- #include "SFformats.h"
- #include "ViewsMenu.h"
- #include "RoundRobin.h"
- #include "LoadSaveMT.h"
- #include "InputFocus.h"
-
- /* Local headers */
- #include "FNCIconbar.h"
- #include "FNCMenu.h"
- #include "Utils.h"
- #include "Main.h"
- #include "PreQuit.h"
- #include "Scan.h"
- #include "FilePerc.h"
-
- #define WimpVersion 310
-
- /* This is the MINIMUM amount of work we do per null poll (though the
- maximum shouldn't be too much greater, since our RoundRobinHandler
- is well written). We null poll as often as possible, like a program
- running under the TaskWindow module. The event mask is used (rather
- than Wimp_PollIdle) to avoid receiving unnecessarily null events. */
- #define NULL_TIME_SLICE 10
-
- _kernel_oserror shared_err_block = {255, ""};
- char taskname[32];
- bool multi_saveboxes = false;
- bool quit_parse_cl = false;
- ObjectId last_savebox = NULL_ObjectId;
- int timeslice = NULL_TIME_SLICE;
- const int fednet_filetypes[11] = {FILETYPE_FEDNET, FILETYPE_POLYOBJS, FILETYPE_BASEMAP, FILETYPE_BASEOBJS, FILETYPE_LEVELMAP, FILETYPE_LEVELOBJS, FILETYPE_SKYCOLS, FILETYPE_MISSION, FILETYPE_PLANETS, FILETYPE_MAPTILES, FILETYPE_ANIMS};
-
- static WimpPollBlock poll_block;
- static IdBlock id_block;
-
- /* ----------------------------------------------------------------------- */
- /* Function prototypes */
-
- static WimpMessageHandler WimpPreQuit_handler, WimpQuit_handler;
- static ToolboxEventHandler autocreate_handler, error_handler;
- static void initialise(void);
- static void process_arguments(int argc, char *argv[]);
- static LoaderFinishedHandler quickdecompress_handler;
- static LoaderFileHandler dummy_loader;
- #ifdef DEBUG
- static void show_budge(void);
- #endif
- static void simple_exit(_kernel_oserror *e);
- static void load_cl_files(int argc, char *argv[]);
-
- /* ----------------------------------------------------------------------- */
- /* Public functions */
-
- int main(int argc, char *argv[])
- {
-
- process_arguments(argc, argv);
- initialise();
- load_cl_files(argc, argv);
- if(quit_parse_cl)
- WimpQuit_handler(NULL, NULL);
-
- /*
- * poll loop
- */
-
- while (TRUE) {
- int event_code;
- event_poll(&event_code, &poll_block, NULL);
- }
- }
-
- /* ----------------------------------------------------------------------- */
- /* Private functions */
-
- static int WimpPreQuit_handler(WimpMessage *message, void *handle)
- {
- int th;
- if(message->hdr.size < 20 || message->data.words[0] == 0)
- th = message->hdr.sender; /* shutdown in progress */
- else
- th = 0; /* just our task */
-
- /* If function returns false then unsaved data */
- if(!TRY_QUIT(th)) {
-
- /* Object by acknowledging message */
- message->hdr.your_ref = message->hdr.my_ref;
- RE(wimp_send_message(Wimp_EUserMessageAcknowledge, message, message->hdr.sender, NULL, NULL))
- }
- return 1; /* claim event */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static int WimpQuit_handler(WimpMessage *message,void *handle)
- {
- exit(EXIT_SUCCESS);
- return 1; /* claim event */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static int autocreate_handler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
- {
- /* Catch auto-created objects and initialise handlers etc. */
- ToolboxObjectAutoCreatedEvent *toace = (ToolboxObjectAutoCreatedEvent *)event;
- if (strcmp(toace->template_name, "Menu") == 0) {
- Menu_initialise(id_block->self_id);
- return 1; /* claim event */
- }
- if (strcmp(toace->template_name, "PreQuit") == 0) {
- PreQuit_initialise(id_block->self_id);
- return 1; /* claim event */
- }
- if (strcmp(toace->template_name, "Iconbar") == 0) {
- Iconbar_initialise(id_block->self_id);
- return 1; /* claim event */
- }
- return 0; /* event not handled */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static int error_handler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
- {
- ToolboxErrorEvent *totee = (ToolboxErrorEvent *)event;
- #ifdef DEBUG
- char str[256];
- sprintf(str, "report errnum: %x errmess: %s", totee->errnum, totee->errmess);
- _kernel_oscli(str);
- #endif
- if(totee->errnum == 0x80b633 || totee->errnum == 0x131c3 || totee->errnum == 255) /* "To save drag...", locked file, user error */
- err_report(totee->errnum, totee->errmess);
- else
- err_complain(totee->errnum, totee->errmess);
- return 1;
- }
-
- /* ----------------------------------------------------------------------- */
-
- static void initialise(void)
- {
- int toolbox_events = 0,
- wimp_messages = 0,
- wimp_version;
-
- hourglass_on();
-
- #ifdef DEBUG
- atexit(show_budge);
- #endif
-
- /*
- * Prevent termination on SIGINT (we use the escape key ourselves)
- */
- signal(SIGINT, SIG_IGN);
-
- /*
- * register ourselves with the Toolbox.
- */
-
- {
- _kernel_oserror *e = toolbox_initialise (0, WimpVersion, &wimp_messages, &toolbox_events, "<FednetCmpRes$Dir>",msgs_get_descriptor(), &id_block, &wimp_version, 0, 0);
- if(e != NULL)
- simple_exit(e);
- }
- strncpy(taskname, msgs_lookup("_TaskName"), sizeof(taskname)-1);
- err_set_taskname(taskname, (wimp_version >= 321));
-
- /*
- * initialise the flex library
- */
-
- flex_init(taskname, (int *)msgs_get_descriptor(), 0); /* (use Wimpslot and own messages file) */
- flex_set_budge(1); /* allow budging of flex when heap extends */
-
- /*
- * initialise the event library.
- */
-
- event_initialise (&id_block);
- event_set_mask (Wimp_Poll_NullMask |
- Wimp_Poll_PointerLeavingWindowMask |
- Wimp_Poll_PointerEnteringWindowMask |
- Wimp_Poll_KeyPressedMask | /* Dealt with by Toolbox */
- Wimp_Poll_LoseCaretMask |
- Wimp_Poll_GainCaretMask);
-
- EF(event_register_toolbox_handler(-1, Toolbox_ObjectAutoCreated, autocreate_handler, 0));
- EF(event_register_toolbox_handler(-1, Toolbox_Error, error_handler, 0));
- EF(event_register_message_handler(Wimp_MPreQuit, WimpPreQuit_handler, 0));
- EF(event_register_message_handler(Wimp_MQuit,WimpQuit_handler,0));
-
- EF(InputFocus_initialise());
- EF(RoundRobin_initialise(timeslice));
-
- /*
- * initialise the Loader library.
- */
-
- EF(loader_initialise(0));
-
- /* Capture Filer double-clicks of compressed files (type &154) and decompress them in-situ */
- EF(loader_register_listener(LISTENER_CLAIM|LISTENER_FILEONLY, FILETYPE_FEDNET, NULL, NULL, dummy_loader, quickdecompress_handler, NULL));
-
- EF(ViewsMenu_create());
-
- hourglass_off();
- }
-
- /* ----------------------------------------------------------------------- */
-
- static void load_cl_files(int argc, char *argv[])
- {
- /*
- * Load any files specified as command-line arguments
- */
-
- for(int i = 1; i < argc; i++) {
- /* anything without a '-' in front is interpreted as a file to decompress */
- if (*argv[i] != '-' && (i < 2 || !ViewsMenu_strcmp_nc(argv[i-1], "-timeslice"))) {
-
- /* get filetype (can't use _kernel_osfile as it doesn't return R6) */
- _kernel_swi_regs regs;
- regs.r[0] = 23;
- regs.r[1] = (int)argv[i];
- if(!E(_kernel_swi(OS_File, ®s, ®s))) {
- /* Does filetype match any known Fednet type? */
- for(int j = 0; j < sizeof(fednet_filetypes)/sizeof(int); j++) {
- if(regs.r[6] == fednet_filetypes[j]) {
- if(!quit_parse_cl)
- /* Start a multi-tasking decompression operation */
- quickdecompress_handler(argv[i], 0, NULL, regs.r[6], NULL);
- else {
- /* A multi-tasking decompression is incompatible with '-quit' */
- _kernel_oserror *err;
- void *buffer_anchor;
- err = perc_operation(FILEPERC_OP_DECOMP, argv[i], 0, &buffer_anchor);
- if(err != NULL)
- err_report(err->errnum, msgs_lookup_sub1("LoadFail", err->errmess));
- else {
- err = perc_operation(FILEPERC_OP_SAVE, argv[i], FILETYPE_DATA, &buffer_anchor);
- if(err != NULL)
- err_report(err->errnum, msgs_lookup_sub1("SaveFail", err->errmess));
- }
- }
- break;
- }
- }
- }
- }
- } /* next parameter */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static void simple_exit(_kernel_oserror *e)
- {
- /* Limited amount we can do with no messages file... */
- wimp_report_error(e, Wimp_ReportError_Cancel, "FednetCmp");
- exit(EXIT_FAILURE);
- }
-
- /* ----------------------------------------------------------------------- */
-
- static void process_arguments(int argc, char *argv[])
- {
- /*
- * Look at command-line parameters
- */
-
- for(int i = 1; i < argc; i++) {
- if(ViewsMenu_strcmp_nc(argv[i], "-quit"))
- quit_parse_cl = true;
- else {
- if(ViewsMenu_strcmp_nc(argv[i], "-multi"))
- multi_saveboxes = true;
- else {
- if(ViewsMenu_strcmp_nc(argv[i], "-timeslice") && i+1 < argc) {
- for(int c = 0; c < strlen(argv[i+1]); c++) {
- if(!isdigit(argv[i+1][c])) {
- strcpy(shared_err_block.errmess, "Bad command line parameters");
- simple_exit(&shared_err_block);
- }
- }
- sscanf(argv[i+1], "%d", ×lice);
- } else {
- if(*argv[i] == '-') {
- /* Catches unknown options, but not time values or file paths */
- strcpy(shared_err_block.errmess, "Bad command line parameters");
- simple_exit(&shared_err_block);
- }
- }
- }
- }
- }
- }
-
- /* ----------------------------------------------------------------------- */
-
- static void quickdecompress_handler(char *file_path, bool data_saved, flex_ptr buffer, int filetype, void *handle)
- {
- /* Deals with Filer double-clicks on compressed files */
- ObjectId process_id = Scan_create(file_path, file_path, false, 0);
- if(process_id != NULL_ObjectId)
- RE(toolbox_show_object(0, process_id, Toolbox_ShowObject_Centre, 0, 0, 0));
- }
-
- /* ----------------------------------------------------------------------- */
-
- static _kernel_oserror *dummy_loader(char *filepath, flex_ptr buffer_anchor)
- {
- return NULL;
- }
-
- /* ----------------------------------------------------------------------- */
-
- //static _kernel_oserror *load_compressed(char *filepath, flex_ptr buffer_anchor)
- //{
- // /* Simple veneer onto multi-tasking decompression function */
- // bool timeup = false;
- // void *handle = NULL;
- // return load_compressedM(filepath, buffer_anchor, &timeup, &handle);
- //}
-
- #ifdef DEBUG
- static void show_budge(void)
- {
- char string[255];
- int prev = flex_set_budge(1);
- sprintf(string, "report Budge state = %d", prev);
- flex_set_budge(prev);
- _kernel_oscli(string);
- }
- #endif
-